package org.rsbot.script.wrappers;

import org.rsbot.bot.Bot;
import org.rsbot.client.HardReference;
import org.rsbot.client.SoftReference;
import org.rsbot.script.Calculations;
import org.rsbot.script.Methods;

/**
 * Inventory/Bank/Shop item.
 * 
 * @verison 1.1 04/25/2011 - Henry Code clean up.
 * */
public class RSItem {

    int id;
    int stack;
    private RSInterfaceComponent component;

    private final Methods methods;

    public RSItem(final int id, final int stack, final Methods methods) {
        this.id = id;
        this.stack = stack;
        this.methods = methods;
    }

    public RSItem(final org.rsbot.client.RSItem item, final Methods methods) {
        id = item.getID();
        stack = item.getStackSize();
        this.methods = methods;
    }

    public RSItem(final RSInterfaceComponent item, final Methods methods) {
        id = item.getComponentID();
        stack = item.getComponentStackSize();
        component = item;
        this.methods = methods;
    }

    /**
     * Clicks item.
     * 
     * @return <tt>True</tt> if component exists and is clicked otherwise
     *         <tt>False</tt>
     */
    public boolean click(final boolean left) {
        return component != null && component.click(left);
    }

    /**
     * Gets this item's definition if available.
     * 
     * @return The <b>RSItemDef</b> or <code>null</code> if unavailable.
     */
    public RSItemDef getDefinition() {
        try {
            final org.rsbot.client.Node ref = methods.calc.findNodeByID(methods.getBot()
                    .getClient().getRSItemDefLoader(), id);

            if (ref != null) {
                if (ref instanceof HardReference)
                    return new RSItemDef(
                            (org.rsbot.client.RSItemDef) (((HardReference) ref)
                                    .get()));
                else if (ref instanceof SoftReference) {
                    final Object def = ((SoftReference) ref).getReference()
                            .get();

                    if (def != null)
                        return new RSItemDef((org.rsbot.client.RSItemDef) def);
                }
            }
            return null;
        } catch (final ClassCastException e) {
            return null;
        }
    }

    /**
     * Gets this item's ID.
     * 
     * @return <b>Integer</b> ID of the itme.
     */
    public int getID() {
        return id;
    }

    /**
     * Gets the component wrapped by this RSItem.
     * 
     * @return The wrapped component or <code>null</code>.
     */
    public RSInterfaceComponent getComponent() {
        return component;
    }

    /**
     * Gets this item's stack size.
     * 
     * @return <b>Integer</b> stack size of the itme.
     */
    public int getStackSize() {
        return stack;
    }

    /**
     * Checks if definition is avaliable.
     * 
     * @return <tt>True</tt> if is otherwise <t>False</tt>
     */
    public boolean hasDefinition() {
        return getDefinition() != null;
    }
}
